package com.cpit.platform.web.controller;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.cpit.platform.common.constant.LogConstant;
import com.cpit.platform.common.entity.TableDataQueryCondition;
import com.cpit.platform.common.utils.LogUtils;
import com.cpit.platform.dto.OperLog;
import com.cpit.platform.service.OperLogService;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.cpit.platform.common.constant.SystemConstant;
import com.cpit.platform.common.entity.Result;
import com.cpit.platform.common.entity.TableJsonData;
import com.cpit.platform.common.excel.ExportExcel;
import com.cpit.platform.common.excel.ImportExcel;
import com.cpit.platform.common.exception.CodeException;
import com.cpit.platform.common.utils.ExcelImportUtils;
import com.cpit.platform.common.utils.ResultUtil;
import com.cpit.platform.dao.SubSystemUserRepository;
import com.cpit.platform.dto.SubSystemUser;
import com.cpit.platform.dto.User;
import com.cpit.platform.log.LogOperator;
import com.cpit.platform.service.UserService;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Controller
@RequestMapping(value = "/user")
public class UserController {

	private final String loggerName = this.getClass().getName();
	private String moduleNmae = "用户：";
	@Autowired
	private UserService userService;
	@Autowired

	private OperLogService operLogService;
	@Autowired
	private SubSystemUserRepository ssURep;
	
	@ApiOperation(value="获取指定用户", notes="根据用户的登录名称查询指定用户")
	@ResponseBody
//	@PreAuthorize("hasAuthority('queryUser')")
    @RequestMapping(value = { "/getUserByName" }, method = RequestMethod.GET)
	public User getUserByName(
			@ApiParam(value = "用户登录名称。") @RequestParam(value = "name", required = true, defaultValue = "") String name) {
		User tmpUser = userService.findByUsername(name);
		return tmpUser;
	}
	
    @ApiOperation(value="创建用户", notes="根据用户实例对象创建用户")
    @ApiImplicitParam(name = "user", value = "用户详细实例", required = true, dataType = "User")
	@ResponseBody
	@PreAuthorize("hasAuthority('createUser')")
	@RequestMapping(value = {"/addUser"}, method = RequestMethod.POST)
	public Result<User> addUser(@RequestBody User user) {
    	LogOperator.info(loggerName, "create user:" + user);
		if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword())
				 || StringUtils.isEmpty(user.getAuthType())|| StringUtils.isEmpty(user.getOrganizationId())
				) {
			writeLog(LogConstant.OPER_CREATE, Result.CODE_FAILED,"用户信息不全，请补充！");
			return ResultUtil.error(Result.CODE_FAILED, "用户信息不全，请补充！");
		} else {
			if(user.getSubSystem() == null) {
				user.setSubSystem(SystemConstant.PLATFORM_ID);
			}
			User tmpUser = userService.findByUsername(user.getUsername());
			if (tmpUser == null) {
				userService.insert(user);
				writeLog(LogConstant.OPER_CREATE, Result.CODE_SUCCESS,user.getUsername());
				return ResultUtil.<User>success(user);
			} else {
				writeLog(LogConstant.OPER_CREATE, Result.CODE_FAILED,"用户登录名"+user.getUsername()+"已存在！");
				return ResultUtil.error(Result.CODE_FAILED, "用户登录名已存在！");
			}
		}
	}

    @ApiOperation(value="删除用户", notes="根据用户标识删除用户记录")
	@ResponseBody
	@PreAuthorize("hasAuthority('deleteUser')")
	@RequestMapping(value = { "/delete/{userid}" }, method = RequestMethod.DELETE)
	public Result<Object> deleteUser(
			@ApiParam(value = "用户标识，此处使用内部用ID标识，并非用户的登录名。", required = true) @PathVariable("userid") Integer userid) {
    	LogOperator.info(loggerName, "delete user:" + userid);
		User user = userService.selectByPrimaryKey(userid);
		userService.deleteByPrimaryKey(userid);
		writeLog(LogConstant.OPER_DELETE, Result.CODE_SUCCESS,user.getUsername());
		return ResultUtil.<Object>success(null);
	}

    @ApiOperation(value="修改用户", notes="根据用户实例对象修改用户")
    @ApiImplicitParam(name = "user", value = "用户详细实例", required = true, dataType = "User")
	@ResponseBody
	@PreAuthorize("hasAuthority('modifyUser')")
	@RequestMapping(value = { "/update" }, method = RequestMethod.POST)
	public Result<User> updateUser(@RequestBody User user) {
    	LogOperator.info(loggerName, "updateUser:" + user);
    	if(user.getSubSystem() == null) {
			user.setSubSystem(SystemConstant.PLATFORM_ID);
		}
		userService.updateByPrimaryKeySelective(user);
		writeLog(LogConstant.OPER_MODIFY, Result.CODE_SUCCESS,user.getUsername());
		return ResultUtil.<User>success(user);
	}

    @PreAuthorize("hasAuthority('queryUser')")
	@ResponseBody
	@RequestMapping(value = { "/queryuserlist" }, method = RequestMethod.GET)
	public Result<List> queryUserList() {
		List<User> userList = userService.selectUserList();
		return ResultUtil.<List>success(userList);
	}
    
    
    @PreAuthorize("hasAuthority('queryUser')")
	@ResponseBody
	@RequestMapping(value = { "/queryuserlistNew" }, method = RequestMethod.GET)
	public List<User> queryUserListNew() {
		List<User> userList = userService.selectUserList();
		return userList;
	}


    @ApiOperation(value="查询用户列表", notes="通过条件查询系统中的用户信息" + 
    		"支持分页查询，支持模糊查询。")
    @ResponseBody
    @PreAuthorize("hasAuthority('queryUser')")
    @RequestMapping(value="/queryUser", method = RequestMethod.GET)  
    public Result<List> queryUser(
    		@ApiParam(value = "当前页数， 以1开始。") @RequestParam(value = "page", required = true, defaultValue = "1") int page, 
    		@ApiParam(value = "当前页的内容长度。") @RequestParam(value = "size", required = true, defaultValue = "20") int size, 
    		@ApiParam(value = "排序方式：asc为升序，desc为降序。") @RequestParam(value = "order", required = false, defaultValue = "asc") String order, 
    		@ApiParam(value = "排序字段，与dto中声明的字段名称一致。") @RequestParam(value = "orderBy", required = false, defaultValue = "id") String orderBy, 
    		@ApiParam(value = "模糊搜索的字符串，根据用户的名称字段进行模糊匹配。") @RequestParam(value = "username", required = false, defaultValue = "") String username,
    		@ApiParam(value = "用户输入的组织机构信息，查询该机构下的所有用户数据。") @RequestParam(value = "orgIdCondition", required = false, defaultValue = "") String orgIdCondition) {
    	List<User> userList = userService.findByCondition(page, size, order, orderBy, orgIdCondition, username);
    	return ResultUtil.<List>success(userList);
    }  

    @ApiOperation(value="查询用户列表", notes="通过条件查询系统中的用户信息" + 
			"支持分页查询，支持模糊查询。")
		    @ApiImplicitParams({
		            @ApiImplicitParam(name = "cond", value = "JqGrid的条件对象，由JqGrid根据js参数自动封装。", required = true, dataType = "TableDataQueryCondition")
		    })
	@SuppressWarnings("rawtypes")
	@ResponseBody
	@PreAuthorize("hasAuthority('queryUser')")//有queryAuthority权限的才能访问  
	@RequestMapping(value="/queryUserJqg", method = RequestMethod.GET)  
	public TableJsonData queryUserJqg(TableDataQueryCondition cond) {
		TableJsonData tjd = userService.findByConditionJqg(cond);
		return tjd;
	}  
    
    @ApiOperation(value="导入子系统用户", notes="向系统中导入子系统的用户，用户管理映射关系")
    @PreAuthorize("hasAuthority('createUser')")
    @ResponseBody
	@RequestMapping(value = "/importSubSystemUser", method = RequestMethod.POST, consumes = "multipart/form-data")
	public Result<Integer> upload(
			@ApiParam(value = "子系统用户信息Excel表格。", required = true) @RequestParam("fileupload") MultipartFile file, HttpServletRequest request) {

		String[] title = { "登录名称", "用户密码", "显示名称", "子系统标识" };
		int headerNum = 1;
		int sheetIndex = 0;
		StringBuilder sb = new StringBuilder();
		if (file == null) {
			throw new CodeException(Result.CODE_FAILED, "文件不能为空！");
		}
		String fileName = file.getOriginalFilename();
		// //验证文件名是否合格
		if (!ExcelImportUtils.validateExcel(fileName)) {
			throw new CodeException(Result.CODE_FAILED, "文件必须是excel格式！");
		}
		long size = file.getSize();
		if (StringUtils.isEmpty(fileName) || size == 0) {
			throw new CodeException(Result.CODE_FAILED, "文件不能为空！");
		}

		// 创建导入Excel对象
		ImportExcel ei = null;
		List<SubSystemUser> userlist = null;
		try {
			ei = new ImportExcel(file, headerNum, sheetIndex);

			StringBuilder errorSB = new StringBuilder();
			String errorStr = ei.validateHead(title);
			errorSB.append(errorStr);

			if (!StringUtils.isEmpty(errorSB.toString())) {
				throw new CodeException("1", "文件格式错误！");
			}

			// 获取传入Excel文件的数据，根据传入参数类型，自动转换为对象
			userlist = ei.getDataList(SubSystemUser.class);
			// 插入
			for (SubSystemUser user : userlist) {
				SubSystemUser un = ssURep.findByUsernameAndSubSystem(user.getUsername(), user.getSubSystem());
				if(un != null) {
					sb.append("用户名：" + user.getUsername() + " 已存在;");
					continue;
				}
				ssURep.save(user);
			}

		} catch (Exception e) {
			LogOperator.err(loggerName, "import user error", e);
			return ResultUtil.error(Result.CODE_FAILED, e.getMessage());
		}
		if(sb.length() == 0) {
			return ResultUtil.success();
		} else {
			return ResultUtil.error(Result.CODE_FAILED, sb.toString());
		}
	}
    
    @PreAuthorize("hasAuthority('queryUser')")
    @ApiOperation(value="查询所有子系统用户", notes="查询所有子系统用户")
	@ResponseBody
	@RequestMapping(value = { "/queryAllSubSystemUsers" }, method = RequestMethod.GET)
	public Result<List> queryAllSubSystemUsers() {
		return userService.queryAllSubSystemUsers();
	}
    
    @ApiOperation(value="查询子系统用户列表", notes="通过条件查询系统中的子系统用户信息" + 
			"支持分页查询，支持模糊查询。")
		    @ApiImplicitParams({
		            @ApiImplicitParam(name = "cond", value = "JqGrid的条件对象，由JqGrid根据js参数自动封装。", required = true, dataType = "TableDataQueryCondition")
		    })
    @ResponseBody
    @PreAuthorize("hasAuthority('queryUser')")
    @RequestMapping(value="/querySubSystemUserJqg", method = RequestMethod.GET)  
    public TableJsonData queryAllSubSystemUsers(TableDataQueryCondition cond) {
    	TableJsonData r = userService.findSsUserByConditionJqg(cond);
    	return r;
    }  
    
    @PreAuthorize("hasAuthority('queryUser')")
    @ApiOperation(value="查询用户角色", notes="根据用户的ID查询用户角色信息")
	@ResponseBody
	@RequestMapping(value = { "/queryUserRolesByUserId/{userid}" }, method = RequestMethod.GET)
	public Result<List> queryUserRolesByUserId(
			@ApiParam(value = "用户ID。", required = true) @PathVariable("userid") Integer userid) {
		return userService.queryUserRolesByUserId(userid);
	}

    @PreAuthorize("hasAuthority('queryUser')")
    @ApiOperation(value="查询用户对应的子系统用户", notes="根据用户的ID查询用户对应的子系统用户信息")
	@ResponseBody
	@RequestMapping(value = { "/querySubSystemUsersByUserId/{userid}" }, method = RequestMethod.GET)
	public Result<List> querySubSystemUsersByUserId(
			@ApiParam(value = "用户ID。", required = true) @PathVariable("userid") Integer userid) {
    	return userService.querySubSystemUsersByUserId(userid);
	}
    
    @PreAuthorize("hasAuthority('queryUser')")
    @ApiOperation(value="查询某个子系统下的全部用户", notes="根据子系统的ID查询其中包含的用户信息")
	@ResponseBody
	@RequestMapping(value = { "/querySubSystemUsersBySystemId/{systemid}" }, method = RequestMethod.GET)
	public Result<List> querySubSystemUsersBySystemId(
			@ApiParam(value = "用户ID。", required = true) @PathVariable("systemid") Integer systemid) {
    	return userService.querySubSystemUsersBySystemId(systemid);
	}
    
    @ApiOperation(value="修改用户的子系统映射关系", notes="根据用户子系统映射关系")
    @ApiImplicitParam(name = "user", value = "用户详细实例，只包含id和subsystemUsers字段即可。", required = true, dataType = "User")
	@ResponseBody
	@PreAuthorize("hasAuthority('modifyUser')")
	@RequestMapping(value = { "/updateSubsystemUserMapping" }, method = RequestMethod.POST)
	public Result<User> updateUserToSubsustemUser(@RequestBody User user) {
    	LogOperator.info(loggerName, "updateUser:" + user);
		userService.updateUserToSubsustemUser(user);
		writeLog(LogConstant.OPER_MODIFY, Result.CODE_SUCCESS,user.getUsername());
		return ResultUtil.<User>success(user);
	}
    
    @ApiOperation(value="导出子系统用户", notes="将系统中的全部子系统用户信息导出到excel文件。")
    @PreAuthorize("hasAuthority('queryUser')")
	@RequestMapping(value = { "/exportSubsystemUserList" }, method = RequestMethod.GET)
	public String exportUserList(HttpServletRequest request, HttpServletResponse response) {
		String date = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
		String fileName = "SubSystemUser_" + date + ".xlsx";
		List<SubSystemUser> userList = this.ssURep.findAll();

		try {
			new ExportExcel("子系统用户信息", SubSystemUser.class).setDataList(userList).write(response, fileName).dispose();
		} catch (IOException e) {
			LogOperator.err(loggerName, "export user info failed!", e);
		}
		return null;
	}
    
    @ApiOperation(value="删除子系统用户", notes="根据子系统用户标识删除用户记录")
	@PreAuthorize("hasAuthority('deleteUser')")
	@RequestMapping(value = { "/deleteSubSystemUser/{userid}" }, method = RequestMethod.DELETE)
    @ResponseBody
	public Result<Object> deleteSubSystemUser(
			@ApiParam(value = "子系统用户标识，此处使用内部用ID标识，并非用户的登录名。", required = true) @PathVariable("userid") Integer userid) {
    	LogOperator.info(loggerName, "delete subsystem user:" + userid);
		User user = userService.selectByPrimaryKey(userid);
    	userService.deleteSubSystemUserById(userid);
		writeLog(LogConstant.OPER_DELETE, Result.CODE_SUCCESS,user.getUsername());
		return ResultUtil.<Object>success(null);
	}
	private  void  writeLog(String op,String result, String detail){
		OperLog operLog = LogUtils.createOperLog(LogConstant.MODULE_CONFIG,op,result,moduleNmae+detail);
		operLogService.writeLog(operLog);
	}
}
